-----------------------------------------------------------------------------------------------------------------------------------------
--解析globalTableTokenTable生成要执行的命令到globalTableCommandTable
-----------------------------------------------------------------------------------------------------------------------------------------
--print("Command Parse lua")
local localStrLuaName="CommandParse.lua"
-----------------------------------------------------------------------------------------------------------------------------------------
--全局变量存储全局信息
-----------------------------------------------------------------------------------------------------------------------------------------
local localTableTargetNameTable		= {}
local localTableTargetSrcTable		= {}
local localTableTargetTypeTable		= {}
-- need extract
local localTableIncludeDirectoriesTable	= {}
-- need extract
local Link_DirectoriesTable	= {}
local Target_Link_LibrariesTargetTable	= {}
--table that contain table need extract
local Target_Link_LibrariesLibTable	= {}
local Add_SubdirectoryTable	= {}
local tmpFolderByteCode = globalStrCurrentDir.."/ByteCode"
local include_CFlagsCommandStr = ""
local linkPathFlagCommandStr = ""

-----------------------------------------------------------------------------------------------------------------------------------------
--common tools 
-----------------------------------------------------------------------------------------------------------------------------------------
require(globalStrModuleUtilities)
-----------------------------------------------------------------------------------------------------------------------------------------
--include_directories Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function include_directoriesParse(tokenCounter)
	local ret = parseCommonSamilar(tokenCounter,localTableIncludeDirectoriesTable,globalTableTokenTable)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--link_directories Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function link_directoriesParse(tokenCounter)
	local ret = parseCommonSamilar(tokenCounter,Link_DirectoriesTable,globalTableTokenTable)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--add_library Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function add_libraryParse(tokenCounter)
--	Target名称
	local ret,index = parseCommonHead(tokenCounter,localTableTargetNameTable,globalTableTokenTable)
	local tmpTypeTable = {}
	for i = 1,3 do
		local nextToken = globalTableTokenTable[ret]
		ret = ret + 1
		if nil == nextToken then
			globalTableErrorHandlerInfo["luaFile"] = localStrLuaName
			globalTableErrorHandlerInfo["Resean"] = "error need )"
			globalTableErrorHandlerInfo["Token"] = globalTableTokenTable[tokenCounter]
			globalTableErrorHandlerInfo["Position"] = tokenCounter
			dofile(globalStrLLMakeErrorHandler)
		end
		if "STATIC" == nextToken or "SHARED" == nextToken  or "MODULE" == nextToken then
			table.insert(tmpTypeTable,nextToken)
		elseif ")" == nextToken then
			break
		else
			ret = ret -1
			break
		end
	end
--	Target种类( Default "STATIC")
	if 0 == table.maxn(tmpTypeTable) then
		table.insert(tmpTypeTable,"STATIC")
	end
	localTableTargetTypeTable[index] = tmpTypeTable
--	Target代码
	ret = parseCommonTail(ret,localTableTargetSrcTable,globalTableTokenTable,index)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--add_executable Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function add_executableParse(tokenCounter)
--	Target名称
	local ret,index = parseCommonHead(tokenCounter,localTableTargetNameTable,globalTableTokenTable)
--	Target种类
	localTableTargetTypeTable[index] = {"EXEC"}
--	Target代码
	ret = parseCommonTail(ret,localTableTargetSrcTable,globalTableTokenTable,index)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--target_link_libraries Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function target_link_librariesParse(tokenCounter)
--	Target名称
	local ret,index = parseCommonHead(tokenCounter,Target_Link_LibrariesTargetTable,globalTableTokenTable)
--	Target使用的Lib库
	ret = parseCommonTail(ret,Target_Link_LibrariesLibTable,globalTableTokenTable,index)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--add_subdirectoryParse Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function add_subdirectoryParse(tokenCounter)
--	subdirectory
	local ret = parseCommonSamilar(tokenCounter,Add_SubdirectoryTable,globalTableTokenTable)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--add_definitionsParse Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function add_definitionsParse(tokenCounter)
--	subdirectory
	local ret = parseCommonSamilar(tokenCounter,globalTableDefinitions,globalTableTokenTable)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--add_required_packageParse Command解析函数开始
-----------------------------------------------------------------------------------------------------------------------------------------
function add_required_packageParse(tokenCounter)
--	subdirectory
	local ret = parseCommonSamilar(tokenCounter,globalTableRequiredPackageTable,globalTableTokenTable)
	return ret
end
-----------------------------------------------------------------------------------------------------------------------------------------
--生成命令函数群
-----------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------
--SrcCommandGen根据代码文件名字生成编译命令
-----------------------------------------------------------------------------------------------------------------------------------------
function SrcCommandGen(src)
--以" . "分割文件名字	
	local tmpTokenTable = {}
	local tmpToken ={}
	local counter = 1
	while 1 do
		local ch = string.byte(src,counter)
		counter = counter + 1
		if nil == ch then
			break
		end
		local split = 0
-- 遇到" . "
		if "." == string.char(ch) then
			split = 1
		end
--分割
		if 1 == split then
			local tmpcout = table.maxn(tmpToken)
			if 0 < tmpcout then
				local tokenstring = table.concat(tmpToken,"")
				table.insert(tmpTokenTable,tokenstring)
				tmpToken ={}
			end
--不用分割
		else
			table.insert(tmpToken,string.char(ch))
		end
	end
--最后的Token
	local tmpcout = table.maxn(tmpToken)
	if 0 < tmpcout then
		local tokenstring = table.concat(tmpToken,"")
		table.insert(tmpTokenTable,tokenstring)
		tmpToken ={}
	end	
	local baseName = table.concat(tmpTokenTable,".",1,table.maxn(tmpTokenTable)-1)
	local tailString = tmpTokenTable[table.maxn(tmpTokenTable)]
	if nil == tailString or nil == baseName then
		globalTableErrorHandlerInfo["luaFile"] = localStrLuaName
		globalTableErrorHandlerInfo["Resean"] = "Error unknown source code type"
		globalTableErrorHandlerInfo["Token"] = baseName
		dofile(globalStrLLMakeErrorHandler)
	end
--	print(src)
	src = globalStrSourceRoot.."/"..src
	local baseName = luaGetBaseName(baseName)
	if nil == baseName then
		local ret = {}
		return  ret,nil
	end
	local objName = tmpFolderByteCode.."/"..baseName..".bc"
	local defaultCflags = globalTableSystemCompilerOption["cflags"]
	local requiredCflags=""
	for i,v in pairs(globalTableRequiredPackageTable) do
		local index = string.lower(v).."_cflags"
		local tmpCflags = globalTableSystemCompilerOption[index]
		if nil ~= tmpCflags then
			requiredCflags = requiredCflags..tmpCflags
		end
	end
	if nil == defaultCflags then
		defaultCflags = ""
	end
	local defines = table.concat(globalTableDefinitions," ")
	local ret = {src,"-o",objName,table.concat(globalTableCFLAGSTable," "),defaultCflags,requiredCflags,defines}
	tailString = string.lower(tailString)
--.c
	if "c" == tailString then
		table.insert(ret,1,"${CC}")
	elseif "cpp" == tailString or "cc" == tailString or "cp" == tailString or "cx" == tailString or "cxx" == tailString then
--.cpp .cc .cp .cx
		table.insert(ret,1,"${CXX}")
		table.insert (ret,table.concat(globalTableCXXFLAGSTable," "))
	elseif "asm" == tailString then 
--.asm
		table.insert(ret,1,"${AS}")
--header file
	elseif "h" == tailString then
		ret = {}
		objName = nil
--Warning Unknown file type
	else
		print("Warning Unknown file type "..src)
		ret = {}
		objName = nil
	end
	return ret,objName
end

-----------------------------------------------------------------------------------------------------------------------------------------
--src2ByteCodeCommandGen根据代码文件名字生成编译命令
-----------------------------------------------------------------------------------------------------------------------------------------
function src2ByteCodeCommandGen(SrcTable)
	local objNameTmp ={}
	for i,v in pairs(SrcTable) do
		tmpTargetCommand,bName = SrcCommandGen(v)
		if nil ~= bName then
			table.insert(objNameTmp,bName)
		end
		if 0 < table.maxn(tmpTargetCommand) then
			local tmpTargetCommandStr = table.concat(tmpTargetCommand," ")
			table.insert(globalTableCommandTable,tmpTargetCommandStr)
		end
	end
	return objNameTmp
end
-----------------------------------------------------------------------------------------------------------------------------------------
--LinkOptionByteCodeCommandGen根据代码文件名字生成编译命令
-----------------------------------------------------------------------------------------------------------------------------------------
function LinkOptionByteCodeCommandGen(target)
	local tmpLibOption= {}
	local libNameTable = Target_Link_LibrariesLibTable[target]
	if nil == libNameTable then
		return nil
	end
	for i,v in pairs(libNameTable) do
--自己定义的Lib库直接连接ByteCode
		local selfLibPath = globalTableTargetPathTable[v];
		if nil ~= selfLibPath then
			table.insert(tmpLibOption,selfLibPath)
--系统或者第三方的Lib库
		else
			local libName = skipHeadSpace(v)
			if nil ~= libName then
--				table.insert(tmpLibOption,string.format('%s%s',"-l",v))
			end
		end
	end
	local ret = table.concat(tmpLibOption," ")
	return ret 
end
-----------------------------------------------------------------------------------------------------------------------------------------
--linkByteCodeCommandGen根据代码文件名字生成编译命令
-----------------------------------------------------------------------------------------------------------------------------------------
function linkByteCodeCommandGen(target,typeTable,targetNameByteCode)
	local tmpTargetCommand = {}
	local tagetLocal = ""
	local libString = ""
	if "EXEC" == typeTable[1] then
		tagetLocal = tmpFolderByteCode.."/"..target 
		tmpTargetCommand = {"${LD_EXE}","-o",tagetLocal,targetNameByteCode}
		table.insert(tmpTargetCommand,table.concat(globalTableLDFLAGSTable," "))
		--Lib -l 追加
		libString = LinkOptionByteCodeCommandGen(target)
		if nil ~= libString then
			table.insert(tmpTargetCommand,libString)
		end
	elseif "SHARED" == typeTable[1] then
		tagetLocal = tmpFolderByteCode.."/".."lib"..target..".bc" 
		tmpTargetCommand = {"${LD_LIB}","-o",tagetLocal,targetNameByteCode}
		--Lib -l 追加
		libString = LinkOptionByteCodeCommandGen(target)
		if nil ~= libString then
			table.insert(tmpTargetCommand,libString)
		end
	elseif "STATIC" == typeTable[1] then
		tagetLocal = tmpFolderByteCode.."/".."lib"..target..".bc" 
		tmpTargetCommand = {"${LD_LIB}"," -o ",tagetLocal,targetNameByteCode}
	elseif "MODULE" == typeTable[1] then
		print("now ignore MODULE")
	else
		print("impossible")
	end
--命令追加
	if 0 < table.maxn(tmpTargetCommand) then
		local tmpTargetCommandStr = table.concat(tmpTargetCommand," ")
		table.insert(globalTableCommandTable,tmpTargetCommandStr)
	end
-- add target path to global 
	globalTableTargetPathTable[target] = tagetLocal;
	local targetDepen = target..";type="..typeTable[1]
	
	local libPath = table.concat(Link_DirectoriesTable," ")
	if nil == libPath then
		libPath = " "
	end
	targetDepen = targetDepen..";path="..libPath
	
	local libTable = Target_Link_LibrariesLibTable[target]
	local libName = ""
	if "table" == type(libTable) then
		libName = table.concat(libTable," ")
	elseif "string" == type(libTable) then
		libName = libTable
	end
	if nil == libName then
		libName = " "
	end
	targetDepen = targetDepen..";lib="..libName
	table.insert(globalTableTargetDependenceTable,targetDepen)
end

--for i,v in pairs(globalTableTokenTable) do 
--	print(i,v)
--end
-----------------------------------------------------------------------------------------------------------------------------------------
--Token解析
-----------------------------------------------------------------------------------------------------------------------------------------
--local tokenNumber = table.maxn(globalTableTokenTable)
local tokenCounter = 1
while 1 do
	local token = globalTableTokenTable[tokenCounter]
	if nil == token then
		break
	end
	token = string.lower(token)
	if "include_directories" == token then
		tokenCounter = include_directoriesParse(tokenCounter)
	elseif "link_directories" == token then
		tokenCounter = link_directoriesParse(tokenCounter)
	elseif "add_library" == token then
		tokenCounter = add_libraryParse(tokenCounter)
	elseif "add_executable" == token then
		tokenCounter = add_executableParse(tokenCounter)
	elseif "target_link_libraries" == token then
		tokenCounter = target_link_librariesParse(tokenCounter)
	elseif "add_subdirectory" == token then
		tokenCounter = add_subdirectoryParse(tokenCounter)
	elseif "add_definitions" == token then
		tokenCounter = add_definitionsParse(tokenCounter)
	elseif "add_required_package" == token then
		tokenCounter = add_required_packageParse(tokenCounter)
	else
		tokenCounter = tokenCounter + 1
	end
--	print(token)
end
-----------------------------------------------------------------------------------------------------------------------------------------
--debug
-----------------------------------------------------------------------------------------------------------------------------------------
--debug_dump_Table("globalTableSetVarTable",globalTableSetVarTable)
--debug_dump_Table("globalTableSetDataTable",globalTableSetDataTable)
--print("-----------------------")
--if globalBoolLuaDebugOutputFlag then
--	debug_dump_Table("localTableIncludeDirectoriesTable",localTableIncludeDirectoriesTable)
--	debug_dump_Table("Link_DirectoriesTable",Link_DirectoriesTable)
--	debug_dump_Table("localTableTargetNameTable",localTableTargetNameTable)
--	debug_dump_Table("localTableTargetSrcTable",localTableTargetSrcTable)
--	debug_dump_Table("localTableTargetTypeTable",localTableTargetTypeTable)
--	debug_dump_Table("Target_Link_LibrariesTargetTable",Target_Link_LibrariesTargetTable)
--	debug_dump_Table("Target_Link_LibrariesLibTable",Target_Link_LibrariesLibTable)
--end
-----------------------------------------------------------------------------------------------------------------------------------------
--降低Table的深度
-----------------------------------------------------------------------------------------------------------------------------------------
localTableTargetNameTable = reduceTableDepth(localTableTargetNameTable)
localTableTargetSrcTable = reduceTableDepth(localTableTargetSrcTable)
localTableIncludeDirectoriesTable = reduceTableDepth(localTableIncludeDirectoriesTable)
Link_DirectoriesTable = reduceTableDepth(Link_DirectoriesTable)
Target_Link_LibrariesTargetTable = reduceTableDepth(Target_Link_LibrariesTargetTable)
Target_Link_LibrariesLibTable = reduceTableDepth(Target_Link_LibrariesLibTable)
-----------------------------------------------------------------------------------------------------------------------------------------
--追加到全局变量里面
-----------------------------------------------------------------------------------------------------------------------------------------
globalTableTargetNameTable = jointTable(globalTableTargetNameTable,localTableTargetNameTable)
globalTableTargetSrcTable = jointTable(globalTableTargetSrcTable,localTableTargetSrcTable)
globalTableTargetTypeTable = jointTable(globalTableTargetTypeTable,localTableTargetTypeTable)
-----------------------------------------------------------------------------------------------------------------------------------------
--debug
-----------------------------------------------------------------------------------------------------------------------------------------
if globalBoolLuaDebugOutputFlag then
	print("-----------------------")
	debug_dump_Table("localTableIncludeDirectoriesTable",localTableIncludeDirectoriesTable)
	debug_dump_Table("Link_DirectoriesTable",Link_DirectoriesTable)
	debug_dump_Table("localTableTargetNameTable",localTableTargetNameTable)
	debug_dump_Table("localTableTargetSrcTable",localTableTargetSrcTable)
	debug_dump_Table("localTableTargetTypeTable",localTableTargetTypeTable)
	debug_dump_Table("Target_Link_LibrariesTargetTable",Target_Link_LibrariesTargetTable)
	debug_dump_Table("Target_Link_LibrariesLibTable",Target_Link_LibrariesLibTable)
	print("-----------------------")
end
-----------------------------------------------------------------------------------------------------------------------------------------
--include_directories 展开
-----------------------------------------------------------------------------------------------------------------------------------------
local include_CFlagsCommand = {}
for i,v in pairs(localTableIncludeDirectoriesTable) do 
	if "table" == type(v) then
		for j,x in pairs(v) do
			if "string" == type(x) then
				local tmpstring = "-I"..globalStrSourceRoot.."/"..x
				table.insert(include_CFlagsCommand,tmpstring)
			end
		end
	end
	if "string" == type(v) then
		local tmpstring = "-I"..globalStrSourceRoot.."/"..v
		table.insert(include_CFlagsCommand,tmpstring)
	end
end
-----------------------------------------------------------------------------------------------------------------------------------------
--link_directories 展开
-----------------------------------------------------------------------------------------------------------------------------------------
local linkPathFlagCommand = {string.format('%s%s',"-L./",tmpFolderByteCode)}
for i,v in pairs(Link_DirectoriesTable) do 
	if "table" == type(v) then
		for j,x in pairs(v) do
			if "string" == type(x) then
				local tmpstring = string.format('%s%s',"-L",x)
				table.insert(linkPathFlagCommand,tmpstring)
			end
		end
	end
	if "string" == type(v) then
		local tmpstring = string.format('%s%s',"-L",v)
		table.insert(linkPathFlagCommand,tmpstring)
	end
end
-----------------------------------------------------------------------------------------------------------------------------------------
--command string
-----------------------------------------------------------------------------------------------------------------------------------------
include_CFlagsCommandStr = table.concat(include_CFlagsCommand," ")
linkPathFlagCommandStr = table.concat(linkPathFlagCommand," ")
table.insert(globalTableCFLAGSTable,include_CFlagsCommandStr)
table.insert(globalTableLDFLAGSTable,linkPathFlagCommandStr)
-----------------------------------------------------------------------------------------------------------------------------------------
--debug
-----------------------------------------------------------------------------------------------------------------------------------------
--print(include_CFlagsCommandStr)
--print(linkPathFlagCommandStr)

-----------------------------------------------------------------------------------------------------------------------------------------
--ByteCode文件夹生成
-----------------------------------------------------------------------------------------------------------------------------------------
local tmpTargetCommand = {"${MKDIR}",tmpFolderByteCode}
if 0 < table.maxn(tmpTargetCommand) then
	local tmpTargetCommandStr = table.concat(tmpTargetCommand," ")
	table.insert(globalTableCommandTable,tmpTargetCommandStr)
end
-----------------------------------------------------------------------------------------------------------------------------------------
--生成编译命令主要循环
-----------------------------------------------------------------------------------------------------------------------------------------
for i,v in pairs(localTableTargetNameTable) do 
	local tmpTargetCommand = {}
--代码编译成ByteCode命令
	local objNameTmp = src2ByteCodeCommandGen(localTableTargetSrcTable[v])
--生成的BC文件，合并成一个文件
	local objNameTmpStr = table.concat(objNameTmp," " )
	local targetNameByteCode = string.format('%s%s%s%s%s',tmpFolderByteCode,"/","LLMakeAutoGenName_",v,".bc")
	tmpTargetCommand = {"${BC_LINK}","-o",targetNameByteCode,objNameTmpStr}
	if 0 < table.maxn(tmpTargetCommand) then
		local tmpTargetCommandStr = table.concat(tmpTargetCommand," ")
		table.insert(globalTableCommandTable,tmpTargetCommandStr)
	end
--链接ByteCode命令
	linkByteCodeCommandGen(v,localTableTargetTypeTable[v],targetNameByteCode)
--目标生成链接命令
end
-----------------------------------------------------------------------------------------------------------------------------------------
--打印Command
-----------------------------------------------------------------------------------------------------------------------------------------
--if globalBoolLuaDebugOutputFlag then
--	for i,v in pairs(globalTableCommandTable) do 
--		print(i,v)
--	end
--end
-----------------------------------------------------------------------------------------------------------------------------------------
--子目录处理
-----------------------------------------------------------------------------------------------------------------------------------------
local backupGlobalStrLLMakeListsFile = globalStrLLMakeListsFile
local backupGlobalStrSourceRoot = globalStrSourceRoot
local backupGlobalStrCurrentDir = globalStrCurrentDir
for i,v in pairs(Add_SubdirectoryTable) do 
	table.insert(globalTableCommandTable,"${MKDIR} "..backupGlobalStrCurrentDir.."/"..v)
	
	local pathToken = parsePathe2Token(backupGlobalStrLLMakeListsFile)
	local path = table.concat(pathToken,"/",1,table.maxn(pathToken) -1 )
	globalStrLLMakeListsFile = path.."/"..v.."/"..pathToken[ table.maxn(pathToken)]
	globalStrSourceRoot = backupGlobalStrSourceRoot.."/"..v
	globalStrCurrentDir = backupGlobalStrCurrentDir.."/"..v
	dofile(globalStrLLMakeHomeScriptPath.."/DoSubdirectory.lua")
end
